﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Com.Maiyoule.GsmSms {
    class Util {
        /// <summary>
        /// 奇偶互换 (+F)
        /// </summary>
        /// <param name="str">要被转换的字符串</param>
        /// <returns>转换后的结果字符串</returns>
        public static string ParityChange(string str) {
            string result = string.Empty;

            if (str.Length % 2 != 0) {//奇字符串 补F
                str += "F";
            }
            for (int i = 0; i < str.Length; i += 2) {//奇偶互换
                result += str[i + 1];
                result += str[i];
            }

            return result;
        }

        /// <summary>
        /// 判断字符串中是否不含中文字符（是否是ASCII字符串）
        /// </summary>
        /// <param name="str">要判断的字符串</param>
        /// <returns>bool值 是ASCII字符串，返回True；否则false</returns>
        public static bool IsASCII(string str) {
            int strLen = str.Length;

            //字符串的字节数，字母占1位，汉字占2位,注意，一定要UTF8
            int byteLen = System.Text.Encoding.UTF8.GetBytes(str).Length;

            //字符数和字节数相等，则全部是ASCII码字符；不相等 则字节数大于字符数 含有汉字字符
            return (strLen == byteLen);
        }

        /// <summary>
        /// 十六进制字符串转二进制字节串
        /// </summary>
        /// <param name="hex">十六进制字符串</param>
        /// <returns>转化得到的byte[]</returns>
        public static byte[] Hex2Bin(string hex) {
            byte[] bin = new byte[hex.Length / 2];  //结果字节串

            for (int i = 0; i < hex.Length; i += 2) {
                //两个字符一组 转化为一个字节
                bin[i / 2] = (byte)Convert.ToByte((hex[i].ToString() + hex[i + 1].ToString()), 16);
            }

            return bin;
        }

        /// <summary>
        /// byte数组转换为字符串 byte最高位0 忽略 每个byte 7个字符
        /// </summary>
        /// <param name="bytes">byte数组</param>
        /// <returns>结果字符串</returns>
        public static string Bin2BinStringof8Bit(byte[] bytes) {
            string result = string.Empty;

            foreach (byte b in bytes) {
                string tmp = Convert.ToString(b, 2);
                while (tmp.Length < 8) {
                    tmp = "0" + tmp;        //前导零补足8bit
                }
                result += tmp;
            }

            return result;
        }

        /// <summary> 
        /// 二进制字符串转化为16进制字符串 每4位一个十六进制字符
        /// </summary>
        /// <param name="bin">二进制字符串</param>
        /// <returns></returns>
        public static string BinStringof8Bit2AsciiwithReverse(string bin) {
            string temp = bin;
            byte[] bytes = new byte[temp.Length / 7];

            //二进制 不是7倍数 去除前导0
            temp = temp.Remove(0, temp.Length % 7);

            for (int i = 0; i < temp.Length; i += 7) {
                bytes[i / 7] = Convert.ToByte(temp.Substring(i, 7), 2);
            }

            Array.Reverse(bytes);

            return Encoding.ASCII.GetString(bytes);
        }

        /// <summary>
        /// 二进制字符串转换为16进制字符串
        /// </summary>
        /// <param name="bin"></param>
        /// <returns></returns>
        public static string BinString2HexString(string bin) {
            return string.Format("{0:x}",Convert.ToInt32(bin,2)).ToUpper();
        }
        /// <summary>
        /// 十进制转为十六进制（补足前导0）
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string Otc2HexString(int num) {
            string result = Convert.ToString(num, 16);
            if(result.Length%2==1){
                result = "0" + result;
            }
            return result;
        }
        /// <summary>
        /// 十六进制字符串转换为二进制字符串
        /// </summary>
        /// <param name="hexstr"></param>
        /// <returns></returns>
        public static string HexString2BinString(string hexstr) {
            int num = Int32.Parse(hexstr, System.Globalization.NumberStyles.HexNumber);
            return Oct2BinString(num,true);
        }
        /// <summary>
        /// 十进制转二进制字符串
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string Oct2BinString(int num) {
            return Oct2BinString(num, false);
        }
        /// <summary>
        /// 十进制转二进制字符串
        /// </summary>
        /// <param name="num">数字</param>
        /// <param name="dock">是否需要前导零</param>
        /// <returns></returns>
        public static string Oct2BinString(int num, bool dock) {
            if (dock) {
                return Convert.ToString(num, 2).PadLeft(8, '0');
            } else {
                return Convert.ToString(num, 2);
            }
        }

        /// <summary>
        /// 二进制字符串转10进制
        /// </summary>
        /// <param name="binstr"></param>
        /// <returns></returns>
        public static Int16 BinString2Oct(string binstr) {
            return Convert.ToInt16(binstr, 2);
        }

        /// <summary>
        /// 十六进制字符串转十进制
        /// </summary>
        /// <param name="hexstr"></param>
        /// <returns></returns>
        public static Int32 HexString2Oct(string hexstr) {
            return Convert.ToInt32(hexstr,16);
        }


        /// <summary>
        /// 7Bit 编码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string PDU7BitEncoding(string str) {
            if(str.Length>160){
                return null;
            }
            if (!IsASCII(str)) {
                return null;

            }
            byte[] packedBytes = PduBitPacker.PackBytes(Encoding.ASCII.GetBytes(str));
            return PduBitPacker.ConvertBytesToHex(packedBytes);
        }

        /// <summary>
        /// 7Bit 解码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string PDU7BitDecoding(string str) {
            byte[] packedBytes = PduBitPacker.ConvertHexToBytes(str);
            byte[] unpackedBytes = PduBitPacker.UnpackBytes(packedBytes);

            return Encoding.ASCII.GetString(unpackedBytes);
        }

        /// <summary>
        /// 8Bit 编码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string PDU8BitEncoding(string str) {
            StringBuilder sb = new StringBuilder();
            byte[] buf = Encoding.ASCII.GetBytes(str);
            sb.Append(buf.Length.ToString("X2"));
            for (int i = 0; i < buf.Length; i++) {
                sb.Append(buf[i].ToString("X2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 使用8-bit进行解码
        /// </summary>
        /// <param name="s">要解码的字符串</param>
        /// <returns>解码后的字符串</returns>
        public static string PDU8BitDecoding(string s) {
            byte[] buf = new byte[s.Length / 2];
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i += 2) {
                buf[i / 2] = byte.Parse(s.Substring(i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
            }
            return Encoding.ASCII.GetString(buf);
        }


        /// <summary>
        /// 中文短信息UCS2编码
        /// </summary>
        /// <param name="s">要编码的中文字符串</param>
        /// <returns>信息长度及编码后的字符串</returns>
        public static string PDUCS2Encoding(string s) {
            StringBuilder sb = new StringBuilder();
            byte[] buf = Encoding.Unicode.GetBytes(s);
            sb.Append(buf.Length.ToString("X2"));
            for (int i = 0; i < buf.Length; i += 2) {
                sb.Append(buf[i + 1].ToString("X2"));
                sb.Append(buf[i].ToString("X2"));
            }
            return sb.ToString();
        }
        /// <summary>
        /// 中文短信息UCS2解码
        /// </summary>
        /// <param name="s">要解码的信息</param>
        /// <returns>解码后的中文字符串</returns>
        public static string PDUCS2Decoding(string s) {
            byte[] buf = new byte[s.Length];
            for (int i = 0; i < s.Length; i += 4) {
                buf[i / 2] = byte.Parse(s.Substring(2 + i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                buf[i / 2 + 1] = byte.Parse(s.Substring(i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
            }
            return Encoding.Unicode.GetString(buf);
        }
    }
}
